/* quad.c:
 */


#include "quad.h"
#include "fixedall.h"

QUAD *Quadlist;                 /* free list for QUADs */

void Q_Init(n)          /* Initialize space for n Qedges */
     int n;
{
  Quadlist = (QUAD *) FA_Aligned_Alloc(sizeof(QUAD),  4 * n, "QUADs");
}

/* Q_MakeEdge:
 *      Creates the topology structure for a directed quad-edge.
 */

Qedge *Q_MakeEdge(freelist)
     QUAD **freelist;           /* adr of ptr to list of QUADs. RETURNED! */
{
  Qedge *e;

  e = (Qedge *) FA_new(freelist);

  /* Set: e.Onext, e.Dnext, e.Lnext, e.Rnext */
  Q_ONEXT(e)         = e;
  Q_ONEXT(Q_SYM(e))  = Q_SYM(e);
  Q_ONEXT(Q_ROT(e))  = Q_IROT(e);
  Q_ONEXT(Q_IROT(e)) = Q_ROT(e);
  return e;
}


/* Q_Splice:
 *      Given directed Qedges a and b, Splice affects the topology of
 *      the two Qedge rings a Org, and b Org as follows:
 *
 *          1.  if the two rings are distinct, Splice will combine 
 *              them into one. 
 *
 *          2.  if the two rings are exactly the same, Splice will 
 *              break it into two separate pieces.
 *
 *      The cuts will occur immediately after a and b in counterclockwise
 *      order.
 */
void Q_Splice(a,b)
     Qedge *a, *b;
{
  Qedge *_a       = Q_ROT( Q_ONEXT(a));
  Qedge *_b       = Q_ROT( Q_ONEXT(b));
  Qedge *aOnext   = Q_ONEXT( b);
  Qedge *bOnext   = Q_ONEXT( a);
  Qedge *_aOnext  = Q_ONEXT(_b);
  Qedge *_bOnext  = Q_ONEXT(_a); 
  
  Q_ONEXT( a) =  aOnext;
  Q_ONEXT( b) =  bOnext;
  Q_ONEXT(_a) = _aOnext;
  Q_ONEXT(_b) = _bOnext;
}


Qedge *MakeQedge(org, dest, left, right)
     void *org, *dest, *left, *right;
{
  Qedge *e;                     /* Make and initialize a quad edge */

  e = Q_MakeEdge(&Quadlist);
  Q_ORG(e) = org;
  Q_DEST(e) = dest;
  Q_LEFT(e) = left;
  Q_RIGHT(e) = right;
  return (e);
}

